
package com.suzj.extraenchantments.util;

import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerChunkCache;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.level.TicketType;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.Level;


public class TeleportHelper {
    public static boolean canDoTeleport(Level world, Player player) {
        if (world.isClientSide) {
            return true;
        } else {
            var spawnDim = ((ServerPlayer)player).getRespawnDimension();
            return world.dimension() == spawnDim;
        }
    }

    public static void teleportPlayerToSpawn(Level world, Player player) {
        if (!world.isClientSide) {
            var spawnDim = ((ServerPlayer)player).getRespawnDimension();
            Level world1 = world;
            if (canDoTeleport(world, player)) {
                if (world.dimension() != spawnDim) {
                    world1 = world.getServer().getLevel(spawnDim);
                }

                player.stopRiding();
                if (player.isSleeping()) {
                    player.stopSleeping();
                }

                if (world1 != null) {
                    BlockPos spawnPoint = ((ServerPlayer)player).getRespawnPosition();
                    if (spawnPoint != null) {
                        boolean force = false;
                        var optional = Player.findRespawnPositionAndUseSpawnBlock((ServerLevel)world1, spawnPoint, ((ServerPlayer)player).getRespawnAngle(), force, true);
                        if (optional.isPresent()) {
                           var pos =  optional.get();
                            doTeleport(player, world, world1, pos.x(), pos.y(), pos.z());
                            return;
                        }
                    }

                    spawnPoint = ((ServerLevel)world1).getSharedSpawnPos();
                    doTeleport(player, world, world1, (double)spawnPoint.getX() + (double)0.5F, (double)spawnPoint.getY(), (double)spawnPoint.getZ() + (double)0.5F);
                }

            }
        }
    }

    private static void doTeleport(Player player, Level origin, Level target, double x, double y, double z) {
        target.playSound((Player)null, player.getX(), player.getY(), player.getZ(), SoundEvents.ENDERMAN_TELEPORT, SoundSource.PLAYERS, 1.0F, 1.0F);
        if (origin != target) {
            ((ServerChunkCache)target.getChunkSource()).addRegionTicket(TicketType.POST_TELEPORT, new ChunkPos(new BlockPos((int) x, (int) y, (int) z)), 1, player.getId());
            ((ServerPlayer)player).teleportTo((ServerLevel)target, x, y, z, player.getYRot(), player.getXRot());
        } else {
            player.teleportTo(x, y, z);
        }

        if (player.fallDistance > 0.0F) {
            player.fallDistance = 0.0F;
        }

        target.playSound((Player)null, x, y, z, SoundEvents.ENDERMAN_TELEPORT, SoundSource.PLAYERS, 1.0F, 1.0F);
    }
}
